import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import java.io.File;

import java.awt.Color; 
import java.awt.Font;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
//继承JFrame 为了直接复用swing框架中窗口管理的能力
//为了子类可以直接调用JFrame public 的方法

//ActionListener 是java中事件处理机制的核心部分
//为了建立计算器组件和用户操作之间的相应机制
public class Calculator extends JFrame implements ActionListener{

    private MediaPlayer mediaPlayer = null; // 显式初始化为null
    private boolean isMusicPlaying = false; // 新增：播放状态标记（避免重复创建播放器）
    private boolean isMusicPaused = false; // 新增：暂停状态标记

    private boolean isInArray(String str, String[] array) {
        for (String s : array) {
            if (s.equals(str)) return true;
        }
        return false;
    }

    //上下两个容器面板，文本框区域 按钮区域
    private JPanel north,center;

    //文本框 显示计算过程，结果或日期
    private JTextField field;

    //按钮
    private JButton[] btns;
    // 时间功能变量
    private boolean isTimeShowing = false; // 时间显示状态
    private Timer timeTimer; // 定时器
    private String userInput = ""; // 保存用户输入内容（避免时间覆盖）
    // 记录当前输入是否在数字模式下（用于小数点判断）
    private boolean inNumberMode = false;

    // 颜色定义（保留原定义）
    private final Color INPUT_BG_COLOR = Color.WHITE; // 输入框背景色（白色）
    private final Color NUMBER_BTN_COLOR = new Color(255, 255, 204); // 浅黄色（数字键）
    private final Color OPERATOR_BTN_COLOR = new Color(255, 204, 204); // 浅粉色（操作符键）

    // 新增：播放音乐方法
    private void playMusic() {
        Platform.runLater(() -> {
            if (mediaPlayer == null) { // 仅首次创建实例
                // 注意：路径中的反斜杠需要转义（使用双反斜杠）
                String musicPath = "C:\\Users\\86151\\Desktop\\_- Merry Christmas Mr. Lawrence (1).wav";
                Media media = new Media(new File(musicPath).toURI().toString());
                mediaPlayer = new MediaPlayer(media);
                
                // 播放结束后重置状态
                mediaPlayer.setOnEndOfMedia(() -> {
                    isMusicPlaying = false;
                    isMusicPaused = false;
                    Platform.runLater(() -> field.setText("音乐播放结束"));
                });
            }
            
            if (!isMusicPlaying) { // 避免重复播放
                if (isMusicPaused) {
                    mediaPlayer.play(); // 恢复播放
                } else {
                    mediaPlayer.play(); // 开始播放
                }
                isMusicPlaying = true;
                isMusicPaused = false;
                field.setText("音乐播放中...");
            }
        });
    }

    // 新增：暂停音乐方法
    private void pauseMusic() {
        Platform.runLater(() -> {
            if (mediaPlayer != null && isMusicPlaying && !isMusicPaused) {
                mediaPlayer.pause();
                isMusicPaused = true;
                isMusicPlaying = false;
                field.setText("音乐已暂停");
            }
        });
    }

    //初始化窗口 - 构造器 构造方法 无参构造器
    public Calculator(){
        //设置窗口title
        setTitle("计算器");
        //设置窗口大小
        setSize(1000, 1000);
        //窗口关闭程序
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //设置窗口居中显示
        setLocationRelativeTo(null);
        //初始化界面组件
        initComponent();
        
        // 必须先初始化JavaFX环境
        new JFXPanel();
        
        // 设置窗口显示
        setVisible(true);
        setBackground(Color.gray);
        
        // 启动计算器时播放音乐
        playMusic();
    }

    //初始化界面组件
    private void initComponent() {
        north = new JPanel();
        center = new JPanel();
        field = new JTextField();
        field.setPreferredSize(new Dimension(700, 150));
        field.setEditable(false);
        field.setFont(new Font("SansSerif", Font.BOLD, 25));
        field.setBackground(INPUT_BG_COLOR); // 设置输入框颜色

        // 按钮文本数组
        String[] str = new String[]{
            "7", "8", "9", "+",
            "4", "5", "6", "-",
            "1", "2", "3", "×",
            "0", ".", "=", "÷",
            "C", "B", "T", "S"
        };

        // 按钮分组数组（仅定义一次）
        String[] numberChars = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".", "="};
        String[] operatorChars = {"+", "-", "×", "÷", "S", "T", "B", "C"}; // 注意：S仍属于操作符组以保持原颜色

        // 初始化按钮数组并设置字体
        btns = new JButton[str.length];
        for (int i = 0; i < btns.length; i++) {
            btns[i] = new JButton(str[i]);
            btns[i].setFont(new Font("SansSerif", Font.BOLD, 25));
        }

        // 设置按钮背景色（保留原逻辑，S按钮仍属于operatorChars，颜色为浅粉色）
        for (JButton btn : btns) {
            String text = btn.getText();
            if (isInArray(text, numberChars)) {
                btn.setBackground(NUMBER_BTN_COLOR);
            } else if (isInArray(text, operatorChars)) {
                btn.setBackground(OPERATOR_BTN_COLOR);
            }
        }

        // 设置布局管理器
        north.setLayout(new BorderLayout());
        center.setLayout(new GridLayout(5, 4));

        // 添加组件到面板
        north.add(field, BorderLayout.CENTER);
        for (JButton btn : btns) {
            center.add(btn);
        }
        add(north, BorderLayout.NORTH);
        add(center);

        // 绑定监听和定时器
        for (JButton btn : btns) {
            btn.addActionListener(this);
        }
        timeTimer = new Timer(1000, e -> updateTime());
        timeTimer.setRepeats(true);
    }

    // 更新时间显示
    private void updateTime() {
        String currentTime = LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        field.setText(currentTime);
    }
    
    private void setBtnText(String text) {
        // 文字放到框中
        String currentText = field.getText();

        // 处理特殊功能按钮
        switch (text) {
            case "C":
                // 清空功能
                field.setText("");
                inNumberMode = false;
                break;
            case "B":
                // 退格功能
                if (currentText.length() != 0) {
                    String lastText = currentText.substring(0, currentText.length() - 1);
                    field.setText(lastText);
                    // 更新数字模式状态
                    inNumberMode = !isLastCharOperator(lastText);
                }
                break;
            case "T":
                isTimeShowing = !isTimeShowing;
                if (isTimeShowing) {
                    userInput = currentText; // 保存当前输入
                    timeTimer.start();
                    updateTime();
                } else {
                    timeTimer.stop();
                    field.setText(userInput); // 恢复输入
                    // 恢复后判断是否在数字模式
                    inNumberMode = !isLastCharOperator(userInput);
                }
                break;
            case "S":
                // 根据当前状态决定是播放还是暂停音乐
                if (isMusicPlaying) {
                    System.out.println("S: 暂停音乐");
                    pauseMusic();
                } else {
                    System.out.println("S: 播放音乐");
                    playMusic();
                }
                break;
            case "=":
                // 执行计算后，将结果粘到文本框
                calculate();
                // 计算后重置状态
                inNumberMode = true;
                break;
            case ".":
                // 小数点输入验证
                if (inNumberMode && !hasDecimalPoint(currentText)) {
                    field.setText(currentText + text);
                } else {
                    // 输入框无数字时自动填充0
                    if (currentText.isEmpty() || isLastCharOperator(currentText)) {
                        field.setText("0.");
                        inNumberMode = true; // 标记为数字输入模式
                    }
                }
                break;
            default:
                // 处理数字、操作符和小数点
                if (!isTimeShowing) { // 非时间模式允许输入
                    // 验证输入是否合法
                    if (isNumber(text)) {
                        // 数字输入
                        field.setText(currentText + text);
                        inNumberMode = true;
                    } else if (text.equals(".")) {
                        // 小数点输入验证
                        if (inNumberMode && !hasDecimalPoint(currentText)) {
                            field.setText(currentText + text);
                        }
                    } else if (isOperator(text)) {
                        // 操作符输入验证（移除了减号不能放在开头的限制）
                        field.setText(currentText + text);
                        inNumberMode = false;
                    }
                }
                break;
        }
    }

    // 判断是否为数字
    private boolean isNumber(String text) {
        return text.matches("[0-9]");
    }

    // 判断是否为操作符（S按钮在此处仍被视为操作符，但实际处理为音乐控制）
    private boolean isOperator(String text) {
        return text.equals("+") || text.equals("-") || text.equals("×") || text.equals("÷");
    }

    // 判断最后一个字符是否为操作符
    private boolean isLastCharOperator(String text) {
        if (text.isEmpty()) {
            return false;
        }
        String lastChar = text.substring(text.length() - 1);
        return isOperator(lastChar);
    }

    // 判断当前文本是否已有小数点
    private boolean hasDecimalPoint(String text) {
        if (text.isEmpty()) {
            return false;
        }
        // 只检查当前数字部分是否有小数点
        // 找到最后一个操作符的位置，只检查后面的部分
        int lastOperatorIndex = -1;
        for (int i = 0; i < text.length(); i++) {
            String charAt = text.substring(i, i + 1);
            if (isOperator(charAt)) {
                lastOperatorIndex = i;
            }
        }
        String numberPart = lastOperatorIndex == -1 ? text : text.substring(lastOperatorIndex + 1);
        return numberPart.contains(".");
    }

    private void calculate(){
        //如果表达式里有乘除 要替换为 * /
        //使用计算引擎
        String expression = field.getText();
        expression = expression.replace("×", "*").replace("÷", "/");
        ScriptEngineManager manager = new ScriptEngineManager();
        //初始化计算引擎
        ScriptEngine engine = manager.getEngineByName("javascript");
        //开始计算
        try{
            Object result = engine.eval(expression);
            field.setText(result.toString());
        } catch (ScriptException e){
            //异常处理方式
            field.setText("运算错误");
            e.printStackTrace();
        }
    }
    
    //实现接口中的抽象方法 处理事件
    @Override
    public void actionPerformed(ActionEvent a){
        //捕获ActionListener监听事件
        //System.out.println(a.getSource());
        Object source = a.getSource();
        if(source instanceof JButton){
            JButton btn = (JButton) source;
            String text = btn.getText();

            //System.out.println(text);
            setBtnText(text);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Calculator::new);
    }
}

